bind9 를 아래에 소개한 mysql과 연동하여 운영 하는 것은 상당히 불안정합니다. 제대로 완전하게 만들어진 것이 아니기 때문에 비추천하며 mysql 과 연동하려고 한다면 mydns 를 쓰는 것을 추천합니다.

설치 환경

OS: ubuntu 10.10 아무것도 설치 안한 깨끗한 버전 (VPS)
라이브러리들: apt-get install openssl libssl-dev libmysqlclient-dev dpkg-dev mysql-client

설치 방법

프로그램 설치하기

아래에 들어갑니다.

cd /usr/local/src

bind9 소스를 받습니다.

apt-get source bind9

bind9-~ 폴더로 들어가서 configure 합니다.

./configure --prefix=/usr \
	--mandir=\$${prefix}/share/man \
	--infodir=\$${prefix}/share/info \
	--sysconfdir=/etc/bind \
	--localstatedir=/var/run/bind \
	--enable-threads \
	--with-libtool \
	--enable-shared \
	--enable-static \
	--with-openssl=/usr \
	--with-gnu-ld \
	--with-dlz-mysql;
make;
make install;

합니다. 그럼 설치 됩니다.
실행 파일은 /usr/sbin/named 에 있습니다.
로그는 /var/log/syslog 에 남습니다.

세팅하기

vi /etc/bind/named.conf (.local)

하여 설정파일을 엽니다.

dlz "Mysql zone" {
	database "mysql
		{host=127.0.0.1 dbname=디비명 user=유저 pass=비번}
		{select zone from dns_records where zone = '%zone%'}
		{select ttl, type, mx_priority, case when lower(type)='txt' then concat('\"', data, '\"') when lower(type) = 'soa' then concat_ws(' ', data, resp_person, serial, refresh, retry, expire, minimum) else data end from dns_records where zone = '%zone%' and host = '%record%'}";
};

이렇게 수정합니다. 디비로 쓸 암호비번도 설정합니다.

아, 그리고 이후에 오류가 나서 실행이 안될 경우가 있는데 로그에 $zone$ 토큰이 없다고 한다면 위에 % 를 모두 $ 로 바꾸면 됩니다.

디비스키마

 CREATE TABLE `dns_records` (
	`id` int(11) NOT NULL auto_increment,
	`zone` varchar(64) default NULL,
	`host` varchar(64) default NULL,
	`type` varchar(8) default NULL,
	`data` varchar(64) default NULL,
	`ttl` int(11) NOT NULL default '3600',
	`mx_priority` int(11) default NULL,
	`refresh` int(11) NOT NULL default '3600',
	`retry` int(11) NOT NULL default '3600',
	`expire` int(11) NOT NULL default '86400',
	`minimum` int(11) NOT NULL default '3600',
	`serial` bigint(20) NOT NULL default '2008082700',
	`resp_person` varchar(64) NOT NULL default 'resp.person.email',
	`primary_ns` varchar(64) NOT NULL default 'ns1.yourdns.here',
	`data_count` int(11) NOT NULL default '0',
	PRIMARY KEY  (`id`),
	KEY `host` (`host`),
	KEY `zone` (`zone`),
	KEY `type` (`type`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

위를 통해 테이블을 생성합니다. (CHARSET은 변경하면 안됩니다.)

named.conf

/etc/bind/named.conf (.options) 를 열어서 아래와 같이 변경합니다.

options {
directory "/etc/bind";
// If there is a firewall between you and nameservers you want
// to talk to, you may need to fix the firewall to allow multiple
// ports to talk.  See http://www.kb.cert.org/vuls/id/800113
// If your ISP provided one or more IP addresses for stable
// nameservers, you probably want to use them as forwarders.
// Uncomment the following block, and insert the addresses replacing
// the all-0's placeholder.
// forwarders {
//      0.0.0.0;
// };
auth-nxdomain no;    # conform to RFC1035
listen-on-v6 { any; };
};

directory 에는 직접 # 주석 처리 한건데 에러가 나서 그렇습니다. 에러 안나면 저거 주석 안하는게 맞을겁니다.

/etc/init.d/bind9

#!/bin/sh -e
### BEGIN INIT INFO
# Provides:          bind9
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Should-Start:      $network $syslog
# Should-Stop:       $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start and stop bind9
# Description:       bind9 is a Domain Name Server (DNS)
#        which translates ip addresses to and from internet names
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
# for a chrooted server: "-u bind -t /var/lib/named"
# Don't modify this line, change or create /etc/default/bind9.
OPTIONS=""
RESOLVCONF=no
test -f /etc/default/bind9 && . /etc/default/bind9
test -x /usr/sbin/rndc || exit 0
. /lib/lsb/init-functions
IDFILE=/var/run/named/named.pid
check_network() {
if [ -x /usr/bin/uname ] && [ "X$(/usr/bin/uname -o)" = XSolaris ]; then
IFCONFIG_OPTS="-au"
else
IFCONFIG_OPTS=""
fi
if [ -z "$(/sbin/ifconfig $IFCONFIG_OPTS)" ]; then
#log_action_msg "No networks configured."
return 1
fi
return 0
}
case "$1" in
start)
log_daemon_msg "Starting domain name service..." "bind9"
log_action_msg "modprobe..."
modprobe capability >/dev/null 2>&1 || true
log_action_msg "mkdir..."
# dirs under /var/run can go away on reboots.
mkdir -p /var/run/named
log_action_msg "chmod..."
chmod 775 /var/run/named
log_action_msg "chown..."
chown root:bind /var/run/named >/dev/null 2>&1 || true
log_action_msg "! -x /usr/sbin/named..?"
if [ ! -x /usr/sbin/named ]; then
log_action_msg "true.."
log_action_msg "named binary missing - not starting"
log_end_msg 1
fi
log_action_msg "false.."
log_action_msg "! check_network..?"
if ! check_network; then
log_action_msg "true.."
log_action_msg "no networks configured"
log_end_msg 1
fi
log_action_msg "false.."
log_action_msg "start..?"
if start-stop-daemon --start --oknodo --exec /usr/sbin/named \
--pidfile ${PIDFILE} -- $OPTIONS; then
if [ "X$RESOLVCONF" != "Xno" ] && [ -x /sbin/resolvconf ] ; then
echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.named
fi
log_end_msg 0
else
log_action_msg "false.."
log_end_msg 1
fi
;;
stop)
log_daemon_msg "Stopping domain name service..." "bind9"
if ! check_network; then
log_action_msg "no networks configured"
log_end_msg 1
fi
if [ "X$RESOLVCONF" != "Xno" ] && [ -x /sbin/resolvconf ] ; then
/sbin/resolvconf -d lo.named
fi
pid=$(/usr/sbin/rndc stop -p | awk '/^pid:/ {print $2}') || true
if [ -z "$pid" ]; then          # no pid found, so either not running, or error
pid=$(pgrep -f ^/usr/sbin/named) || true
start-stop-daemon --stop --oknodo --quiet --exec /usr/sbin/named \
--pidfile ${PIDFILE} -- $OPTIONS
fi
if [ -n $pid ]; then
while kill -0 $pid 2>/dev/null; do
log_progress_msg "waiting for pid $pid to die"
sleep 1
done
fi
log_end_msg 0
;;
reload|force-reload)
log_daemon_msg "Reloading domain name service..." "bind9"
if ! check_network; then
log_action_msg "no networks configured"
log_end_msg 1
fi
/usr/sbin/rndc reload >/dev/null && log_end_msg 0 || log_end_msg 1
;;
restart)
if ! check_network; then
log_action_msg "no networks configured"
exit 1
fi
$0 stop
$0 start
;;
status)
ret=0
status_of_proc -p ${PIDFILE} /usr/sbin/named bind9 2>/dev/null || ret=$?
exit $ret
;;
*)
log_action_msg "Usage: /etc/init.d/bind9 {start|stop|reload|restart|force-reload|status}"
exit 1
;;
esac
exit 0

참고

DB 조작법 (쿼리법)

# for www.domain.com to resolve to 1.2.3.4
insert into dns_records (zone, host, type, data, mx_priority) values ('domain.com', 'www', 'A', '1.2.3.4', null);
# for domain.com to resolve to 1.2.3.4
insert into dns_records (zone, host, type, data, mx_priority) values ('domain.com', '@', 'A', '1.2.3.4', null);
# for www2.domain.com to alias to www.domain.com;
# note the trailing period in the data field
insert into dns_records (zone, host, type, data, mx_priority) values ('domain.com', 'www2', 'CNAME', 'www.domain.com.', null);
# for mail for domain.com to go to domain.com
# note the trailing period in the data field
insert into dns_records (zone, host, type, data, mx_priority) values ('domain.com', '@', 'MX', 'domain.com.', '0');

출저: http://ubuntuforums.org/showthread.php?t=823578

우분투 시작 서비스 등록하기

등록하기: update-rc.d -f bind9 defaults
해제하기: update-rc.d -f bind9 remove

오류모음

restart 할때 에러

rndc: neither /etc/bind/rndc.conf nor /etc/bind/rndc.key was found
rndc 는 그냥 좋은 기능중 하나인데 ( http://kldp.org/node/48665 ) 설치 안해줘도 필요 없습니다. bind.keys 파일이 있길레 rndc.key 로 바꿔봤는데, 호구짓이었습니다.

query denied 에러

options 블록에

allow-recursion { any; };
allow-query { any; };
allow-query-cache { any; };

위를 추가합니다.